/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ru.vsu.service;

import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.enterprise.event.Event;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import ru.vsu.domain.Bid;
import ru.vsu.domain.Lot;
import ru.vsu.domain.SystemUser;
import ru.vsu.domain.Thing;
import ru.vsu.domain.dict.ThingType;
import ru.vsu.observer.NewBidEventHandler;

/**
 *  Сервис для создания/редактирования лотов аукциона.
 *
 * @author Roman Velichkin <vrnroman@gmail.com>
 */
@Stateless
public class LotService {

    @PersistenceContext(unitName="JavaForVSUPU")
    private EntityManager em;

    @Inject
    @NewBidEventHandler
    private Event<Long> eventHandler;

    /**
     * Выставить на аукцион товар с заданной начальной ценой.
     * @param sellerId
     * @param thing
     * @param startPrice
     * @return
     */
    public Lot createLotForThing(Thing thing, Integer startPrice) {
        Lot lot = new Lot();
        lot.setStartDate(new Date());
        lot.setThing(thing);
        lot.setStartPrice(startPrice);
        lot.setSeller(thing.getOwner());
        lot = em.merge(lot);
        return lot;
    }


    /**
     * Сделать новую ставку на лот.
     * @param lot
     * @param newPrice
     * @param userId
     * @return
     */
    public boolean addNewBid(Lot lot, Integer newPrice, Long userId) {
        if (lot.isOpen() && lot.getMaxPrice() < newPrice) {
            Bid bid = new Bid();
            bid.setDate(new Date());
            bid.setLot(lot);
            bid.setPrice(newPrice);
            bid.setUser(em.find(SystemUser.class, userId));
            lot.getBids().add(bid);
            lot = em.merge(lot);
            eventHandler.fire(lot.getId());
            return true;
        }
        return false;
    }

    /**
     * Выставлена ли вещь на торги в данный момент.
     * @param thing
     * @return
     */
    public boolean isThingOnSale(Thing thing) {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery cq = cb.createQuery();
        Root<Lot> root = cq.from(Lot.class);
        cq.where(cb.and(
                cb.equal(root.get("thing").get("id"), thing.getId()),
                cb.equal(root.get("open"), 1)));
        cq.select(root);
        List<Lot> result = em.createQuery(cq).getResultList();
        return result != null && !result.isEmpty();
    }

    /**
     * Получить список всех активных аукционов.
     * @return
     */
    public List<Lot> getActiveLots() {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery cq = cb.createQuery();
        Root<Lot> root = cq.from(Lot.class);
        cq.where(cb.equal(root.get("open"), 1));
        cq.select(root);
        return em.createQuery(cq).getResultList();
    }

    public Lot updateLot(Long lotId) {
        Lot lot = em.find(Lot.class, lotId);
        return lot;
    }

    public void closeLot(Long lotId) {
        Lot lot = em.find(Lot.class, lotId);
        lot.setOpen(false);
        lot.getThing().setOwner(lot.getWinner());
        em.merge(lot);
    }

    public void createFakeThingType() {
        ThingType type = new ThingType();
        type.setName("Automobile");
        em.persist(type);
    }
}
